import { AfterViewInit, Component, ElementRef, Injector, Renderer2, ViewChild, ViewContainerRef } from '@angular/core';
import { BsModalRef } from 'ngx-bootstrap/modal';
import { debounceTime, finalize } from 'rxjs/operators';
import { AppConsts } from '@shared/AppConsts';
import { LibraryFileItem,FileLibraryServiceProxy, FindDirectoryInput, FindDirectoryOutput, 
    FindFileListInput, MergeFileInput, EntityDtoOfInt64, MultipartUploadVerifyInput, 
    IPathItem, DirectoryItem, MoveDirectoryInput, EntityDtoOfGuid, MoveOtherDirectoryInput, 
    PagedResultDtoOfLibraryFileItem, MultipartUploadServiceProxy } from '@shared/service-proxies/service-proxies';
import { FileUploadHelper } from '@shared/helpers/FileUploadHelper';
import { fromEvent, Subscription } from 'rxjs';
import { filter as _filter } from 'lodash-es';
import { FindingFileItem, IFileFinderModalOptions } from './file-finder-options';

import { DateTimeService } from '../timing/date-time.service';
import { MenuItem } from 'primeng/api';
import { ContextMenu } from 'primeng/contextmenu';
import { AppBsModalService } from '@shared/common/appBsModal/app-bs-modal.service';
import { DirectoryCreateModalComponent } from './directory-create-modal.component';
import { AppComponentBase } from '@shared/common/app-component-base';
import { DirectoryEditModalComponent } from './directory-edit-modal.component';
import { SelectDirectoryModalComponent } from './select-directory-modal.component';
import { FilePropertiesEditModalComponent } from './file-properties-edit-modal.component';
import { MultipartUploadHelper } from '../multipart-upload/multipart-upload-helper';
import { ChunkContainer, FileChunk, Status } from '../multipart-upload/multipart-upload-option';
import { TokenService } from 'abp-ng2-module';

@Component({
    selector: 'file-finder-modal',
    templateUrl: './file-finder-modal.component.html',
    styleUrls: ['./file-finder-modal.component.less']
})
export class FileFinderModalComponent extends AppComponentBase implements AfterViewInit {

    @ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;

    options: IFileFinderModalOptions;

    loading = false;

    isMultiSelectVal = false;
    get isMultiSelect(): boolean {
        return this.isMultiSelectVal;
    }
    set isMultiSelect(val: boolean) {
       if(val === false){
           this.listData.forEach(item => {
               if (item.selected && !item.isactive) {
                   item.selected = false;

                   const imageElem2 = document.getElementById(item.eleId);
                   if (imageElem2) {
                       let classList = imageElem2.getAttribute('class');
                       if (classList) {
                           classList = classList.replace(' selected', '');
                           imageElem2.setAttribute('class', classList);
                       }
                   }
               }
           });
       }
       this.isMultiSelectVal = val;
    }

    canMultiSelect = true;
   
    containerHeight: number = 460;
    fontHeight: number = 120;
    itemHeight: number = 160;

    // 瀑布流数据
    listData: FindingFileItem[] = [];
    selectedFile: FindingFileItem = null;
    pagedFileParam:FindFileListInput = new FindFileListInput();
    totolCount:number = 0;

    // 文件夹目录
    pathItems: IPathItem[] = [];
    private currentPath :IPathItem;

    canUpload:boolean = false;

    // 下级文件夹清单
    dirItems: DirectoryItem[] = [];
    dicItemsCanEdit: DirectoryItem[] = [];

    // 文件夹右键菜单
    selectedDirItem: DirectoryItem = null;
    ouContextMenuItems: MenuItem[];

    @ViewChild('fileInputEle') fileInputEle: ElementRef;
    @ViewChild('fileInputEle2') fileInputEle2: ElementRef;
    @ViewChild('fileInputEleReplace') fileInputEleReplace: ElementRef;

    @ViewChild('ouContextMenu') ouContextMenu: ContextMenu;  

    permissions: {
        [key:string] :boolean
    } = {};

    get hostEl() {
        return this.vc.element.nativeElement;
    } 

    private subscription : Subscription;

    private _multipartUploadHelper: MultipartUploadHelper;

    constructor(
        injector: Injector,
        public bsModalRef: BsModalRef,
        private _fileLibraryService: FileLibraryServiceProxy,
        private _multipartUploadService: MultipartUploadServiceProxy,
        private renderer: Renderer2,
        private _tokenService: TokenService,
        private _dateTimeService: DateTimeService,
        private _modalService: AppBsModalService
    ) {
        super(injector);

        this._multipartUploadHelper = new MultipartUploadHelper(this.notify, this._tokenService);
    }

    ngAfterViewInit(): void {
        setTimeout((): void => {
            this.containerHeight = Math.floor(window.innerHeight - 200);
        }, 0);

        
        this.InitializeUpload();
    }

    private InitializeUpload() {
        this._multipartUploadHelper.Initialize(4, {
            uploaderUrl: AppConsts.remoteServiceBaseUrl + '/B/EditorFile/LibraryFileUpload',
            partUploaderUrl: AppConsts.remoteServiceBaseUrl + '/B/EditorFile/PartUpload',
            singleUploaderOnBuildItemForm: (fileItem, form) => {
                form.append("replaceFileId", this.container.customData.replaceFileId);
                if (this.container.customData.pathItem.id) {
                    form.append("directoryId", this.container.customData.pathItem.id);
                }

                form.append("fileName", this.container.file.name);
                form.append("fileHash", this.container.hash);
                form.append("fileSize", this.container.file.size);
                form.append("dimensions", this.container.dimensions);
            },
            uploadedCallback: (fileItem) => {
                if (this.uploadingFileQueue.length === 0) {
                    let fileId = this.container.customData.replaceFileId;

                    if (fileId > 0) {
                        this.updateImage(fileItem);
                        this.showFileUpload = false;
                    } else {
                        this.getList(true);
                    }
                } else {
                    this.insertToFirst(fileItem);
                }
            },
            verifyFunction: (t) => {
                return this._multipartUploadService.multipartUploadVerify(t);
            },
            getVerifyInput: (fileContainer) => {
                return new MultipartUploadVerifyInput({
                    fileHash: fileContainer.hash,
                    fileName: fileContainer.file.name,
                    replaceFileId: fileContainer.customData.replaceFileId,
                    directoryId: fileContainer.customData.pathItem.id
                });
            },
            getMergeRequestInput: () => {
                return new MergeFileInput({
                    fileHash: this.container.hash,
                    fileName: this.container.file.name,
                    replaceFileId: this.container.customData.replaceFileId,
                    directoryId: this.container.customData.pathItem.id,
                    fileSize: this.container.file.size,
                    dimensions: this.container.dimensions,
                    count: this.chunks.length
                });
            },
            mergeRequestFunction: (t) => {
                return this._multipartUploadService.mergeFile(t);
            }
        });
    }

    configure(options: IFileFinderModalOptions): void {
        this.options = options;
        this.canMultiSelect = options.multiSelect;
    }

    shown() {
        if (!this.options) {
            throw Error('Should call FileFinderModalComponent.configure once before FileFinderModalComponent.show!');
        }
        
        this.permissions['Pages_Library_Upload'] = this.isGranted('Pages_Library_Upload');
        this.permissions['Pages_Library_Edit_Self'] = this.isGranted('Pages_Library_Edit_Self');
        this.permissions['Pages_Library_Delete_Self'] = this.isGranted('Pages_Library_Delete_Self');
        
        this.permissions['Pages_Directory_Create'] = this.isGranted('Pages_Directory_Create');
        this.permissions['Pages_Directory_Edit_Self'] = this.isGranted('Pages_Directory_Edit_Self');
        this.permissions['Pages_Directory_Delete_Self'] = this.isGranted('Pages_Directory_Delete_Self');
        this.permissions['Pages_Library_Edit'] = this.isGranted('Pages_Library_Edit');
        this.permissions['Pages_Library_Delete'] = this.isGranted('Pages_Library_Delete');

        // 自适应窗口高度并加载数据
        this.checkItemWrapperHeight();

        this.getDirSelectionData(()=>{
            this.openDir();
        });

        // 绑定瀑布流滚动条事件
        this.subscription = fromEvent(this.hostEl,'scroll')
        .pipe( 
            debounceTime(200)
        )
        .subscribe( _ =>{
            const topIns = this.hostEl.scrollTop
            const bottomIns = this.hostEl.scrollHeight - topIns - this.hostEl.offsetHeight   
            if(bottomIns < 200) {  
                this.getList(false);
            } 
        });
    }

    private checkItemWrapperHeight(){
        let aa = this.hostEl as HTMLElement;
        if(aa.clientWidth > 0){
            let newItemHeight = Math.floor(aa.clientWidth / 4) ;
            if(newItemHeight != this.itemHeight){
                this.itemHeight = newItemHeight;
                this.fontHeight = Math.floor(newItemHeight * 0.75) ; 
            }
        }else{
            setTimeout((): void => {
                this.checkItemWrapperHeight();
            }, 300);
        }
    }

    private getDirSelectionData(callback:{():void}){
        this._fileLibraryService.getDirectoriesForSelection().subscribe(result=>{
            this.dicItemsCanEdit = result;
            this.dicItemsCanEdit.forEach(item => {
                item.displayName = Array(item.level + 1).join('  -') + '    ' + item.displayName;
            });
            callback && callback();
        });
    }

    // 打开文件夹
    openDir(path:IPathItem = null): void {
        if(!path){
            path = { displayName: "root", id: null, code: null, path: "root", readOnly: true,isDefault: true};
        }

        this.currentPath = path;
        this.pagedFileParam.directoryCode = path.code;

        this.canUpload = this.checkIsCanUploadFile(path);

        let input = new FindDirectoryInput({ parentId: this.currentPath.id });
        this.loading = true;
        this._fileLibraryService.findSubDirectories(input)
            .pipe(finalize(() => this.loading = false))
            .subscribe((result: FindDirectoryOutput) => {
                this.loading = false;
                this.pathItems = result.pathItems;

                this.dirItems = result.items;
                this.getList(true);
            });
    }

    getDirectoryIcon(item: DirectoryItem): string {

        if(this.permissions['Pages_Library_Edit']){
            return 'text-warning';
        }

        if(item.isDefault){
            return 'font-grey';
        }

        if(item.readOnly){
            return 'font-grey';
        }
            
        return 'text-warning';
    }

    private checkIsCanUploadFile(path:IPathItem){
        let permission = this.permissions['Pages_Library_Upload'];

        if(!permission){
            return false;
        }

        // default文件夹 不可编辑，也不能主动上传文件, 在root上传文件会自动存入uploads
        if(!path.id){
            return true;
        }

        if(path.isDefault){
            return false;
        }

        const owner:boolean = !path.readOnly;
        return this.permissions['Pages_Library_Edit'] || (owner && this.permissions['Pages_Directory_Edit_Self']);
    }

    checkFileEditPermission(file:FindingFileItem){
        let dir = file.pathItems[file.pathItems.length -1];
        
        // default文件夹 下的文件可以编辑
        const owner:boolean = !dir.readOnly && !dir.isDefault;
        return this.permissions['Pages_Library_Edit'] || (owner && this.permissions['Pages_Directory_Edit_Self']);
    }


    checkFileDeletePermission(file:FindingFileItem){
        let dir = file.pathItems[file.pathItems.length -1];
        
        // default文件夹 下的文件可以编辑
        const owner:boolean = !dir.readOnly && !dir.isDefault;
        return this.permissions['Pages_Library_Delete'] || (owner && this.permissions['Pages_Directory_Delete_Self']);
    }

    onDirRightClick(event: MouseEvent, data:DirectoryItem){
        this.selectedDirItem = data;
        this.ouContextMenuItems = this.getDirContextMenuItems(data);
        this.ouContextMenu.show(event);
    }

    createRootDirectory(){
        const bsModalRef = this._modalService.show(DirectoryCreateModalComponent, {
            backdrop: 'static', class: 'modal-lg'
        });

        bsModalRef.content.shown(null);
        bsModalRef.content.openNewDir = (result: DirectoryItem) => {
            this.getDirSelectionData(() => {
                this.openDir(result);
            });
        };
    }

    getDirContextMenuItems(directory: DirectoryItem): any[]{

        const owner:boolean = !directory.readOnly;

        const canEdit = !directory.isDefault && (this.permissions['Pages_Library_Edit'] || (owner && this.permissions['Pages_Directory_Edit_Self']));
        const canAdd = canEdit && this.permissions['Pages_Directory_Create'];
        const canDelete = this.permissions['Pages_Library_Delete'] || (!directory.isDefault && owner && this.permissions['Pages_Directory_Delete_Self']);

        let items = [
            {
                label: this.l('AddSubDirectory'),
                disabled: !canAdd,
                command: () => {
                    const bsModalRef = this._modalService.show(DirectoryCreateModalComponent, {
                        backdrop: 'static', class: 'modal-lg'
                    });
            
                    bsModalRef.content.shown(this.selectedDirItem);
                    bsModalRef.content.openNewDir = (result: DirectoryItem) => {
                        this.getDirSelectionData(() => {
                            this.openDir(result);
                        });
                    };
                }
            },
            {
                label: this.l('Edit'),
                disabled: !canEdit,
                command: (event) => {
                    const bsModalRef = this._modalService.show(DirectoryEditModalComponent, {
                        backdrop: 'static', class: 'modal-lg'
                    });
            
                    bsModalRef.content.shown(this.selectedDirItem);
                    bsModalRef.content.callback = (result: DirectoryItem) => {
                        this.openDir(this.currentPath);
                    };
                }
            },
            {
                label: this.l('UpSort'),
                disabled: !canEdit,
                command: (event) => {
                    const input = new EntityDtoOfGuid({
                        id: this.selectedDirItem.id
                    })
                    this._fileLibraryService.upSortDirectory(input)
                    .subscribe(result => {
                        this.notify.success(this.l('OrderSuccessSuccessfully'));
                        this.openDir(this.currentPath);
                    });
                }
            },
            {
                label: this.l('DownSort'),
                disabled: !canEdit,
                command: (event) => {
                    const input = new EntityDtoOfGuid({
                        id: this.selectedDirItem.id
                    })
                    this._fileLibraryService.downSortDirectory(input)
                    .subscribe((result) => {
                        this.notify.success(this.l('OrderSuccessSuccessfully'));
                        this.openDir(this.currentPath);
                    });
                }
            },
            {
                label: this.l('MoveTo'),
                disabled: !canEdit,
                command: (event) => {
                    const bsModalRef = this._modalService.show(SelectDirectoryModalComponent, {
                        backdrop: 'static', class: 'modal-lg'
                    });
            
                    bsModalRef.content.shown(this.dicItemsCanEdit);
                    bsModalRef.content.callback = (parentId: string) => {
                        if(!parentId){
                            return;
                        }
                        this._fileLibraryService.moveDirectory(new MoveDirectoryInput({
                            id: this.selectedDirItem.id,
                            newParentId: parentId
                        }))
                        .subscribe(result=>{
                            let newParent = this.dicItemsCanEdit.find(tt=> tt.id === parentId);
                            if(newParent !== null){
                                this.openDir(newParent);
                            }else{
                                this.openDir(this.currentPath);
                            }
                        })
                    };
                }
            },
            {
                label: this.l('Delete'),
                disabled: !canDelete,
                command: () => {
                    this.message.confirm(
                        this.l('DeleteWarningMessage', this.selectedDirItem.displayName),
                        this.l('AreYouSure'),
                        isConfirmed => {
                            if (isConfirmed) {
                                this._fileLibraryService.deleteDirectory(this.selectedDirItem.id).subscribe(() => {
                                    this.notify.success(this.l('SuccessfullyDeleted'));
                                    this.openDir(this.currentPath);
                                });
                            }
                        }
                    );
                }
            }
        ];

        return items;
    }

    private locking: boolean = false;
    // 勾选文件
    selectFile(fileItem: FindingFileItem) {
        if(this.locking || !fileItem){
            return;
        }

        const imageElem = document.getElementById(fileItem.eleId);
        if (!imageElem) {
            // image was not found in DOM
            return;
        }

        
        this.locking = true;

        try {
            // 选中的改为未选中
            if (fileItem.isactive) {
                fileItem.isactive = false;
                fileItem.selected = false;
                if (this.selectedFile !== null && fileItem.id === this.selectedFile.id) {
                    this.selectedFile = null;
                }

                let classList = imageElem.getAttribute('class');
                if (classList) {
                    classList = classList.replace(' isactive', '').replace(' selected', '');
                    imageElem.setAttribute('class', classList);
                }

                this.locking = false;

                return;
            }

            // 切换当前选中项
            this.listData.forEach(item => {
                let hasChange = false;
                if (item.isactive) {
                    item.isactive = false;
                    hasChange = true;
                }
                if (!this.isMultiSelect && item.selected) {
                    item.selected = false;
                    hasChange = true;
                }

                if (hasChange) {
                    const imageElem2 = document.getElementById(item.eleId);
                    if (imageElem2) {
                        let classList = imageElem2.getAttribute('class');
                        if (classList) {
                            classList = classList.replace(' isactive', '');
                            if (!this.isMultiSelect) {
                                classList = classList.replace(' selected', '');
                            }
                            imageElem2.setAttribute('class', classList);
                        }
                    }
                }
            });

            fileItem.selected = true;
            fileItem.isactive = true;
            this.selectedFile = fileItem;

            let classList = imageElem.getAttribute('class');
            if (classList) {
                if (classList.indexOf('isactive') < 0) {
                    classList += ' isactive';
                }
                if (classList.indexOf('selected') < 0) {
                    classList += ' selected';
                }
                imageElem.setAttribute('class', classList);
            }
        } catch (ex) {
            console.log(ex);
        }

        this.locking = false;
    }

    // 确认提交
    confirmIt() {
        if (this.options.callback) {
            let pics = _filter(this.listData, (item) => item.selected);
            this.options.callback(pics);

            this.close();
            return;
        }

        // ckeditor编辑回调
        let list = _filter(this.listData, (item) => item.selected)
            .map(item => {
                return { 'item': item, 'html': '' }
            });

        if (list.length > 0) {
            let self = this;

            let insertHtml = function(){
                let html = list.map(t=> t.html).join('<br>');
                self.options.editor.insertHtml(html);
                self.close();
            };

            let count = 0;
            list.forEach(item=>{
                if(item.item.exName === 'mp4'){
                    item.html = "<div class=\"video-box\">";
                    item.html +="	<video class=\"video-js vjs-default-skin vjs-big-play-centered\" controls=\"\" data-setup=\"{}\" playsinline=\"true\"  ";
                    item.html +="	    style=\"width: 100%; height: 100%;\" webkit-playsinline=\"true\"  ";
                    item.html +="	   x-webkit-airplay=\"allow\" x5-video-player-type=\"h5\">";
                    item.html +="		<source src=\"" + item.item.absoluteUrl +"\" type=\"video/mp4\" />";
                    item.html +="	<p class=\"vjs-no-js\">To view this video please enable JavaScript, and consider upgrading to a web browser that<a href=\"http://videojs.com/html5-video-support/\" target=\"_blank\">supports HTML5 video</a></p>";
                    item.html +="	</video>";
                    item.html +="</div>";
                    count++;
                    if(count ===list.length){
                        insertHtml();
                    }
                    return;
                }

                if(item.item.icon){
                    item.html = '<a href="' + item.item.absoluteUrl + '"  target="_blank" >'+ item.item.fileName +'</a>';
                    count++;
                    if(count ===list.length){
                        insertHtml();
                    }
                    return;
                }

                let img = new Image();
                let src = item.item.absoluteUrl;
                img.src = src;
 
                img.onload = function () {
                    item.html = '<img alt="'+item.item.title +'" src="' + src + '"  width="' + img.width + '"  height="' + img.height + '">';
                    count++;
                    if(count ===list.length){
                        insertHtml();
                    }
                }
                img.onerror= function () {
                    count++;
                    if(count ===list.length){
                        insertHtml();
                    }
                }
            });
        }
    }

    // 加载瀑布流文件
    getList(firstPage: boolean) {
        if (this.loading) {
            return;
        }

        if (!firstPage && this.pagedFileParam.skipCount >= this.totolCount) {
            return;
        }

        this.loading = true;
        
        if (firstPage) {
            this.clearImageFromGallery();
            this.selectedFile = null;
            this.pagedFileParam.skipCount = 0;
            this.pagedFileParam.maxResultCount = 20;
        }

        this._fileLibraryService.findFileList(this.pagedFileParam)
            .pipe(finalize(() => this.loading = false))
            .subscribe((result: PagedResultDtoOfLibraryFileItem) => {
                this.pagedFileParam.skipCount += result.items.length;
                this.totolCount =  result.totalCount;

                let newData :FindingFileItem[] =[];
                result.items.forEach(item => {
                    let d = this.fileItemToData(item);
                    newData.push(d);
                });
                this.listData = this.listData.concat(newData);

                this.addImagesToView(newData);
            });
    }

    private fileItemToData(item: LibraryFileItem){
        let d = new FindingFileItem(item);
                    d.icon = FileUploadHelper.getIcon(item.exName);
                    d.sizeStr = FileUploadHelper.getFileSize(item.size);
                    d.isImage = FileUploadHelper.isImage(item.exName);
                    d.absoluteUrl = FileUploadHelper.getUrl(item.fileUrl);
                    d.downloadUrl = FileUploadHelper.getDownUrl(item.exName,item.fileUrl);
                    d.eleId = "i"+ d.id;
        return d;
    }

    private addImagesToView(files: FindingFileItem[]): void {
        files.forEach(file => {

            const imageWrapper = this.fileDataToElement(file);

            let container = document.getElementById('media-library-main-list');
            this.renderer.appendChild(container, imageWrapper);
        });
    }

    private fileDataToElement(file: FindingFileItem) {
        const imageWrapper = this.renderer.createElement('li');
        imageWrapper.setAttribute('class', 'col-sm-3 li-paddiing');
        imageWrapper.setAttribute('id', file.eleId);
        imageWrapper.setAttribute('style', `height:${this.itemHeight}px;overflow:hidden;`);
        imageWrapper.addEventListener('click', () => {
            this.selectFile(file);
        });

        if (file.icon) {
            let divItem = this.renderer.createElement('div');
            divItem.setAttribute('class', 'file-item');

            let iItem = this.renderer.createElement('i');
            iItem.setAttribute('class', file.icon);
            this.renderer.appendChild(divItem, iItem);

            let spanItem = this.renderer.createElement('span');
            spanItem.innerText = file.fileName;
            this.renderer.appendChild(divItem, spanItem);

            this.renderer.appendChild(imageWrapper, divItem);
        } else {
            let imgItem = this.renderer.createElement('img');
            imgItem.setAttribute('src', file.absoluteUrl);

            imgItem.setAttribute('class', `pic-size bg-gray`);
            this.renderer.appendChild(imageWrapper, imgItem);
        }
        return imageWrapper;
    }

    private removeImageFromGallery(file: FindingFileItem){
        const index = this.listData.findIndex(item => item.id === file.id);
        if (index < 0) {
            // image was not found, this is probably an error
            return;
        }

        const imageElem = document.getElementById(file.eleId);
        if (!imageElem) {
            // image was not found in DOM
            return;
        }

        let container = document.getElementById('media-library-main-list');
        this.renderer.removeChild(container,imageElem);

        this.listData.splice(index, 1);
    }

    private updateImage(data: LibraryFileItem){
        let file = this.fileItemToData(data);
        file.absoluteUrl = file.absoluteUrl +'?d='+FileUploadHelper.randomId();

        const index = this.listData.findIndex(item => item.id === file.id);
        if (index < 0) {
            // image was not found, this is probably an error
            return;
        }

        this.listData[index].absoluteUrl = file.absoluteUrl;

        const imageElem = document.getElementById(file.eleId);
        if (!imageElem) {
            // image was not found in DOM
            return;
        }

        let container = document.getElementById('media-library-main-list');
        
        const imageWrapper = this.fileDataToElement(this.listData[index]);

        this.renderer.insertBefore(container,imageWrapper,imageElem);
        this.renderer.removeChild(container,imageElem);
    }

    private insertToFirst(data: LibraryFileItem){
        let file = this.fileItemToData(data);
        const imageWrapper = this.fileDataToElement(file);

        let container = document.getElementById('media-library-main-list');
        
        if(this.listData.length > 0){
            const imageElem = document.getElementById(this.listData[0].eleId);
            this.listData.unshift(file);
            if (!imageElem) {
                this.renderer.appendChild(container,imageWrapper);
            }else{
                this.renderer.insertBefore(container,imageWrapper,imageElem);
            }
        }else{
            this.listData.push(file);
            this.renderer.appendChild(container,imageWrapper);
        }
    }

    private clearImageFromGallery(){
        this.listData = [];
        
        this.selectedFile = null;

        let container = document.getElementById('media-library-main-list');

        container.childNodes.forEach(element => {
            this.renderer.removeChild(container,element);
        });
    }

    close(): void {
        this.subscription.unsubscribe();
        this.clearImageFromGallery();
        this.isMultiSelect = false;
        this.bsModalRef.hide();
    }

    delete() {
        if (this.selectedFile) {
            this.message.confirm(this.l('DeleteWarningMessage'), this.l('AreYouSure'),
                (isConfirmed) => {
                    if (!isConfirmed) return;

                    var input = new EntityDtoOfInt64({ id: this.selectedFile.id});
                    this._fileLibraryService.deleteFileFromLibrary(input)
                    .pipe(finalize(() => this.loading = false))
                    .subscribe((result) => {
                        this.removeImageFromGallery(this.selectedFile);
                        
                        this.selectedFile = null;
                        this.notify.success(this.l('SuccessfullyDeleted'));
                    });
                })
        }
    }

    editFileProperties(){
        if (this.selectedFile) {
            const bsModalRef = this._modalService.show(FilePropertiesEditModalComponent, {
                backdrop: 'static', class: 'modal-lg'
            });
    
            bsModalRef.content.shown(this.selectedFile);
            bsModalRef.content.callback = (result: LibraryFileItem) => {
                if(this.selectedFile){
                    this.selectedFile.fileName = result.fileName;
                    this.selectedFile.title = result.title;
                    this.selectedFile.tags = result.tags;
                }
            };
        }
    }

    moveFile(){
        if (this.selectedFile) {
            const bsModalRef = this._modalService.show(SelectDirectoryModalComponent, {
                backdrop: 'static', class: 'modal-lg'
            });
    
            bsModalRef.content.shown(this.dicItemsCanEdit);
            bsModalRef.content.callback = (parentId: string) => {
                if(!parentId){
                    return;
                }
                this._fileLibraryService.moveToOtherDirectory(new MoveOtherDirectoryInput({
                    fileId: this.selectedFile.id,
                    toDirectoryId: parentId
                }))
                .subscribe(result=>{
                    this.openDir(result);
                })
            };
        }
    }

    // 图片预览
    lookOver() {
        if(this.selectedFile && !this.selectedFile.icon){
            abp.event.trigger(AppConsts.EventName.showImageView, this.selectedFile.absoluteUrl);
        }
    }

    // 文件上传 -------------

    // 搜索文件
    chooseFile() {
        if(this.computing){
            return;
        }
        this.fileInputEle.nativeElement.click();
    }
    computing = false;
    fileInputEleChange(e){
        if (e.target.files && e.target.files.length > 0) {
            let file = e.target.files[0];
            e.target.value = null;

            this.computing = true;
            this._multipartUploadHelper.calculateHashSample(file)
            .then((result) => {
                this.pagedFileParam.filter = result;
                this.computing = false;
                this.getList(true);
            });
        }
    }

        
    //选择要上传的文件
    chooseUploadFile() {
        this.fileInputEle2.nativeElement.click();
    }

    fileInputEle2Change(e) {
        if (!this.permission) {
            e.target.value = null;
            return;
        }

        if (e.target.files) {
            let newFiles:File[] = [];
            let files = e.target.files;
            for (const iterator of files) {
                newFiles.push(iterator);
            }
            e.target.value = null;

            let { str1, str2 } = this.checkAllowedFileExname();

            newFiles.forEach(file=>{
                if (!FileUploadHelper.checkExName(file.name, str1)) {
                    this.notify.error(file.name + '：' + this.l('File_Invalid_Type_Error', str2));
                } 
                else if (!FileUploadHelper.checkMaxSize(file.size, abp.custom.fileUploadMaxSize)) {
                    let tempSize = Math.round(file.size / (1024 * 1024) * 100) / 100;
                    this.notify.error(file.name + '：' + this.l('File_SizeLimit_Error', abp.custom.fileUploadMaxSize, tempSize));
                }else{
                    let item = this.getUploadingFileItem(file);
                    this._multipartUploadHelper.uploadingFileQueue.push(item);
                }
            })

            this._multipartUploadHelper.container = null;
            //this.handleUpload();
        }
    }

    // 文件更换
    replaceFile() {
        if (this.status === Status.uploading || this.status === Status.pause || this.showMerging) {
            this.notify.info("正在上传中");
            return;
        }

        if (this.selectedFile) {
            this.fileInputEleReplace.nativeElement.click();
        }
    }
    fileInputEleReplaceChange(e) {
        if (e.target.files && e.target.files.length > 0) {
            let file = e.target.files[0];
            e.target.value = null;

            let { str1, str2 } = this.checkAllowedFileExname();

            if (!FileUploadHelper.checkExName(file.name, str1)) {
                this.notify.error(file.name + '：' + this.l('File_Invalid_Type_Error', str2));
            }
            else if (!FileUploadHelper.checkMaxSize(file.size, abp.custom.fileUploadMaxSize)) {
                let tempSize = Math.round(file.size / (1024 * 1024) * 100) / 100;
                this.notify.error(file.name + '：' + this.l('File_SizeLimit_Error', abp.custom.fileUploadMaxSize, tempSize));
            } else {
                //let exName = FileUploadHelper.getExName(file.name);
                // if(exName !== this.selectedFile.exName){
                //     this.notify.error("选定的文件与原文件格式不同");
                // }

                let item = this.getUploadingFileItem(file);
                item.replaceFileId = this.selectedFile.id;
                this.uploadingFileQueue.length = 0;
                this._multipartUploadHelper.container = item;
                this.handleUpload();
            }
        }
    }


    private checkAllowedFileExname(){
        let str1 = "";
        let str2 = "";
        abp.custom.fileUploadAllowed.forEach(t => {
            let tt = t.substring(1);
            if (str1) {
                str1 += '|';
                str2 += '、';
            }
            str1 += tt;
            str2 += tt;
        });
        return { str1, str2 };
    }


	get showFileUpload(): boolean {
		return this._multipartUploadHelper.showFileUpload;
	}
    set showFileUpload(ou: boolean) {
        this._multipartUploadHelper.showFileUpload = ou;
	}

    get container(): ChunkContainer {
		return this._multipartUploadHelper.container;
	}

    get uploadingFileQueue(): ChunkContainer[] {
		return this._multipartUploadHelper.uploadingFileQueue;
	}

    get chunks(): FileChunk[] {
		return this._multipartUploadHelper.chunks;
	}

    get showHashProgress(): boolean {
		return this._multipartUploadHelper.showHashProgress;
	}
    get showMerging(): boolean {
		return this._multipartUploadHelper.showMerging;
	}
    get uploadProgress(): number {
		return this._multipartUploadHelper.uploadProgress;
	}
    // 默认状态
    get status(): Status {
		return this._multipartUploadHelper.status;
	}

    get cubeWidth(): number {
        return Math.ceil(Math.sqrt(this.chunks.length)) * 16
    }

    getChunkCssClasses(chunk:FileChunk){
        let classes = '';
        if (chunk.progress>0 && chunk.progress<100) {
            classes += ' uploading';
        }
        if (chunk.progress === 100) {
            classes += ' success';
        }

        if (chunk.status=== Status.reject || chunk.status===Status.error) {
            classes += ' error';
        }

        return classes;
    }

    disabledPause(){
        return this.status !== Status.uploading
    }
    canResume(){
        return this.status === Status.pause
    }
    showProgressBar(){
        return this.showMerging || [Status.pause, Status.uploading, Status.error].includes(this.status);
    }

    handleResume() {
        this._multipartUploadHelper.handleResume();
    }

    handlePause() {
        this._multipartUploadHelper.handlePause();
    }

    // 移除一个待上传的文件
    cancelFromQueue(index){
        this._multipartUploadHelper.cancelFromQueue(index);
    }

    handleUpload() {
        this._multipartUploadHelper.handleUpload();
    }

    private getUploadingFileItem(file: File) {
        let item = this._multipartUploadHelper.getUploadingFileItem(file);
        
        item.customData.replaceFileId = 0;
        item.customData.pathItem = this.currentPath;
        
        return item;
    }
}
